# build in python 3.5.2
# 作者：陈常鸿
# 梯度下降
# 函数1：待优化函数f(x),根据输入返回函数值
# 函数2：待优化函数的导数g(x),根据输入返回导数值
# 变量x:保存当前优化过程中的参数值，优化开始时变量初始化为一个随机值，优化过程不断变化直到找到最小值
# 变量grad:保存变量x点处的梯度值
# 变量step:表示艳梯度下降方向行进的步长，就是学习效率
import numpy as np
import matplotlib.pyplot as plt
def momentum(x_start,step,g,discount=0.7):
    x=np.array(x_start,dtype='float64')
    pre_grad=np.zeros_like(x)
    for i in range(50):
        grad=g(x)
        pre_grad=pre_grad*discount+grad*step
        x-=pre_grad
        print('迭代数{0} grad = {1} ,x={2}'.format(i,grad,x))
        if abs(sum(grad))<1e-6:
            break
    return x

def f(x):
    return x[0]*x[0] + 50 * x[1] + x[1]

def g(x):
    return np.array([2*x[0],100*x[1]])


xi=np.linspace(-200,200,1000)
yi=np.linspace(-100,100,1000)
x,y=np.meshgrid(xi,yi)
z=x*x+50*y*y
res,x_arr=momentum([150,75],0.019,g)
